﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using AllTalk.AllTalkProxyService;
using System.ServiceModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Collections.ObjectModel;

namespace AllTalk
{
    internal class ConnectionManager
    {
        private AllTalkProxyServiceClient _client;

        internal bool IsConnected { get; private set; }

        private bool _isInitialized;
        
        public EventHandler<MessageSentEventArgs> MessageSent { get; set; }

        public EventHandler<ConnectionEventArgs> ConnectionCompleted { get; set; }

        public void Connect(string username, string password)
        {
            if (IsConnected)
            {
                return;
            }

            // Due to exceptions in connection we might need to be re-connected.
            if (!_isInitialized)
            {
                Initialize();
            }

            _client.ConnectAsync(new ConnectionParameters { Domain = "www.gmail.com" });
        }

        private void Initialize()
        {
            Debug.Assert(!_isInitialized);

            var binding = new BasicHttpBinding();
            binding.MaxReceivedMessageSize = 4 * 1024 * 1024; // 4 MB

            _client = new AllTalkProxyServiceClient(binding,
               new EndpointAddress(@"http://192.168.1.105:14290/AllTalkService.svc"));

            _client.ConnectCompleted += new EventHandler<ConnectCompletedEventArgs>(client_ConnectCompleted);
            _client.SendCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_SendCompleted);
            _isInitialized = true;
        }

        private void client_ConnectCompleted(object sender, ConnectCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                this.IsConnected = true;
                App.DataModel.CurrentJid = new Jid(e.Result.Jid);
                App.ViewModel.LoadFriendsList(e.Result.RosterXml, e.Result.Jid);
                App.ViewModel.LoadPresence(e.Result.PresenceXml);
                _client.ReceiveMessagesAndPresenceCompleted += new EventHandler<ReceiveMessagesAndPresenceCompletedEventArgs>(_client_ReceiveMessagesAndPresenceCompleted);
                _client.ReceiveMessagesAndPresenceAsync(e.Result.Jid);
            }
            if (this.ConnectionCompleted != null)
            {
                ConnectionCompleted(this, new ConnectionEventArgs(e.Error));
            }
        }

        void _client_ReceiveMessagesAndPresenceCompleted(object sender, ReceiveMessagesAndPresenceCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                App.ViewModel.LoadPresence(e.Result.PresenceXml);
                App.ViewModel.LoadMessages(e.Result.MessageXml);
                App.ViewModel.LoadVcards(e.Result.VcardXml);
                _client.ReceiveMessagesAndPresenceAsync(App.DataModel.CurrentJid.Value);
            }
        }

        internal void SendMessageAsync(ChatMessage message)
        {
            _client.SendAsync(App.DataModel.CurrentJid.Value, message.ToXml(), message);
        }

        void client_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (this.MessageSent != null)
            {
                this.MessageSent(this, new MessageSentEventArgs(e.UserState as ChatMessage, e.Error));
            }
        }

        internal void GetVcardAsync(string email)
        {
            var friends = new ObservableCollection<string>();
            friends.Add(email);
            _client.GetVcardAsync(App.DataModel.CurrentJid.Value, friends);
        }
    }
}
